package com.zhu.zookeeper;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.framework.state.ConnectionStateListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {

        String hostPort = "localhost:2181";
        String path = "/zbook";
        CuratorFramework client= CuratorFrameworkFactory.newClient(
                hostPort, 5000, 5000, new ExponentialBackoffRetry(500, 20));
        client.getConnectionStateListenable().addListener(new ConnectionStateListener() {

            @Override
            public void stateChanged(CuratorFramework client, ConnectionState newState) {

                System.out.println("Zookeeper connection state changed {}."+newState);

                if (newState == ConnectionState.RECONNECTED) {

                    System.out.println("Zookeeper connection has been re-established, will re-subscribe and re-register.");

                    // 重新订阅


                    // 重新发布服务

                }
            }
        });
        client.start();
        register(client,path);
//        subscript(client,path);
//        unregister(client,path);
        Thread.sleep(Integer.MAX_VALUE);

    }
    static void subscript(CuratorFramework client,String path){
        PathChildrenCache newChildrenCache = new PathChildrenCache(client, path, false);
        newChildrenCache.getListenable().addListener(new PathChildrenCacheListener(){
            @Override
            public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
                System.out.println("Child event: {}"+ event);
                switch (event.getType()){
                    case CHILD_ADDED:{
                        System.out.println("CHILD_ADDED");
                        break;}
                    case CHILD_REMOVED:{System.out.println("CHILD_REMOVED");break;}
                    case CHILD_UPDATED:{System.out.println("CHILD_UPDATED");break;}
                }
            }
        });

    }
    static void register(CuratorFramework client,String path) throws Exception {
        if (client.checkExists().forPath(path) == null) {
            client.create().creatingParentsIfNeeded().forPath(path);
        }
        client.create().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {

            @Override
            public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
                if (event.getResultCode() == KeeperException.Code.OK.intValue()) {
                    System.out.println("Register: {} - {}."+"192.168.1.20");
                }

            }
        }).forPath(
                String.format("%s/%s:%s:%s:%s",
                        path,
                        "192.168.1.20",
                        "9090",
                        "10",
                        "10"));
    }

    static void unregister(CuratorFramework client,String path) throws Exception{
        if (client.checkExists().forPath(path) == null) {
            return;
        }
        client.delete().inBackground(new BackgroundCallback() {

            @Override
            public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
                System.out.println("Unregister: {} - {}."+"192.168.1.20");
            }
        }).forPath(
                String.format("%s/%s:%s:%s:%s",
                        path,
                        "192.168.1.20",
                        "9090",
                        "10",
                        "10"));
    }
}
